package me.gavin.di

import com.google.gson.Gson
import me.gavin.TestRepo
import me.gavin.TestViewModel
import me.gavin.net.ClientAPI
import me.gavin.net.HeaderInterceptor
import me.gavin.net.OKHttpCacheInterceptor
import me.gavin.net.OKHttpCacheNetworkInterceptor
import me.gavin.util.CacheHelper
import me.gavin.util.log
import okhttp3.Cache
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.context.KoinContextHandler
import org.koin.core.qualifier.named
import org.koin.dsl.module
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit

val viewModelModule = module {
    viewModel { TestViewModel(get()) }
}

val reposModule = module {
    factory { TestRepo(get()) }
}

val remoteModule = module {

    single<Retrofit> {
        Retrofit.Builder()
            .baseUrl("https://api.gavin.com/")
            .addConverterFactory(ScalarsConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(get()))
            // .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(get(named("default")))
            .build()
    }

    single<OkHttpClient>(named("default")) {
        OkHttpClient.Builder()
            .connectTimeout(15, TimeUnit.SECONDS)
            .readTimeout(15, TimeUnit.SECONDS)
            .writeTimeout(15, TimeUnit.SECONDS)
            .addInterceptor(get<HeaderInterceptor>())
            .addInterceptor(OKHttpCacheInterceptor())
            .addNetworkInterceptor(OKHttpCacheNetworkInterceptor())
            .addInterceptor(HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
                override fun log(message: String) {
                    message.log(tag = "OkHttp")
                }
            }).setLevel(HttpLoggingInterceptor.Level.BODY))
            .cache(get(named("default")))
            .build()
    }

    single<OkHttpClient>(named("images")) {
        OkHttpClient.Builder()
            .addInterceptor(get<HeaderInterceptor>())
            .addInterceptor(HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
                override fun log(message: String) {
                    message.log(tag = "images")
                }
            }).setLevel(HttpLoggingInterceptor.Level.HEADERS))
            .cache(get(named("images")))
            .build()
    }

    single<ClientAPI> { get<Retrofit>().create(ClientAPI::class.java) }

    single { HeaderInterceptor() }

    single(named("default")) { Cache(File(CacheHelper.cacheDir, "responses"), 50 * 1024 * 1024) }

    single(named("images")) { Cache(File(CacheHelper.cacheDir, "images"), 50 * 1024 * 1024) }

    single { Gson() }

}

/* ************************************************************* */

val instanceHolder get() = KoinContextHandler.get()

